package us.versus.them.hmap;

import flash.display.DisplayObject;
import flash.display.Sprite;
import flash.display.MovieClip;
import flash.events.MouseEvent;
import flash.events.Event;

class Mst3 extends LoadableSprite {
	var counter : Int;
	var dx:Float;
	var dy:Float;
	var spawn : Int;

	static var THE_OTHERS = new Array< Mst3 >();

	// this bit sets up the demo
	public static function main() {
		bg();

		var params = flash.Lib.current.loaderInfo.parameters;
		var sprites = cast( params.sprites, String ).split( ',' );

		var x = 0;
		for ( sprite in sprites ) {
			var f = new Mst3(
				params.directory
				, sprite
				, cast( params.directions, String ).split( ',' )
				, cast( params.frames, String ).split( ',' )
				, 'gif'
				, 5
			);
		}
	}

	public static function add( l:Mst3 ) {
		flash.Lib.current.addChild( l );
		THE_OTHERS.push( l );
	}

	public function new ( 
		?dir : String
		, ?sprite : String
		, ?directions : Array< String > 
		, ?frames : Array< String >
		, ?format : String
		, ?spawn : Int
	) {
		super( dir, sprite, directions, frames, format );
		this.reset();
		this.spawn = spawn;
		loaded = loadedx;
	}

	public function khopi() {
		var bobo = new Mst3();
		this.link( bobo );
		return bobo;
	}

	public function reset() {
		this.counter = 0;
		this.x = Gordie.stageWidth() * Math.random();
		this.y = Gordie.stageHeight() * Math.random();
		this.dx = this.dy = 0;
	}

	public function loadedx() {
		flash.Lib.current.addEventListener( Event.ENTER_FRAME , frame );
		flash.Lib.current.addEventListener( MouseEvent.CLICK, click );
		if ( 0 != spawn ) {
			for ( i in 0 ... spawn) {
				Mst3.add( this.khopi() );
			}
		}
	}

	public function click( event : Dynamic ) {
		this.reset();
	}

	public function frame( event : Dynamic ) {
		var xdiff = flash.Lib.current.mouseX - this.x;
		var ydiff = flash.Lib.current.mouseY - this.y;
		this.goDir( this.toDir( xdiff, ydiff ) );
		this.move( xdiff, ydiff );
	}

	public function move( xdiff : Float, ydiff : Float ) {
		var resistance = 10000;
		var damping = 0.9;
		var tooMuch = 1;

		var force = ( 1 + xdiff * xdiff + ydiff * ydiff ) / resistance;
		this.dx += this.bound( xdiff * force, tooMuch );
		this.dy += this.bound( ydiff * force, tooMuch );

		this.dx *= damping;
		this.dy *= damping;

		tooMuch = 4;
		this.dx = this.bound( this.dx, tooMuch );
		this.dy = this.bound( this.dy, tooMuch );
		
		this.x += this.dx;
		this.y += this.dy;

		//// this is a little expensive, but funny
		bouncey_bouncey();
	}

	public function bouncey_bouncey() {
		for ( l in THE_OTHERS ) {
			if ( l != this ) {
				if ( hitTestObject( l ) ) {
					var ox = ( this.x - l.x ) / 4;
					var oy = ( this.y - l.y ) / 4;
					this.dx += ox;
					this.dy += oy;
					l.dx -= ox;
					l.dy -= oy;
				}
			}
		}
	}

	public function bound( value : Float, tooMuch : Float ) {
		return Math.max( Math.min( value, tooMuch ), -tooMuch );
	}

	public function toDir( xdiff : Float, ydiff : Float ) : String {
		return 
			if ( Math.abs( xdiff ) > Math.abs( ydiff ) ) {
				if ( xdiff < 0 ) "lf" else "rt";
			} else {
				if ( ydiff < 0 ) "bk" else "fr";
			}
	}

	public function goDir( dir : String ) {
		this.counter++;
		var often = 6;
		if ( this.counter > often * 2 ) {
			this.counter = 0;
		}
		var frame = if ( this.counter < often ) "1" else "2";
		super.useFrame( dir, frame );
	}

	// this is just dumb junk to make the demo "look cool" ... FAIL!

	public static function bg() {
		var bg = new Sprite();
		var w = Gordie.stageWidth();
		var h = Gordie.stageHeight();
		bg.graphics.beginFill( 0xDDDD99 );
		bg.graphics.drawRect( 0, 0, w, h );
		bg.graphics.endFill();
	
		var x = 0;
		var n = 20;
		while ( x < w ) {
			bg.graphics.lineStyle( 1, 0xAAAA77 );
			bg.graphics.moveTo( x, 0 );
			bg.graphics.lineTo( w, x );
			bg.graphics.lineStyle( 2, 0xEEEEAA );
			bg.graphics.moveTo( x + 1, 0 );
			bg.graphics.lineTo( w, x + 1 );
			x += n;
		}
		x = 0;
		while ( x < h ) {
			bg.graphics.lineStyle( 1, 0xAAAA77 );
			bg.graphics.moveTo( 0, x );
			bg.graphics.lineTo( x, h );
			bg.graphics.lineStyle( 2, 0xEEEEAA );
			bg.graphics.moveTo( 0, x + 1 );
			bg.graphics.lineTo( x + 1, h );
			x += n;
		}

		flash.Lib.current.addChild( bg );
	}
}
